package org.jeecg.modules.wlhy.wlxypt.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.ImageUtil;
import org.jeecg.common.util.PdfUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.third.digitalseal.utils.GeneratePDF;
import org.jeecg.modules.third.ecloud.sdk.util.MD5Util;
import org.jeecg.modules.third.openapi.WaybillRouteService;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.PointDataListVO;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.jeecg.modules.wlhy.utils.HyCfgUtil;
import org.jeecg.modules.wlhy.wlxypt.entity.WlxyptDriver;
import org.jeecg.modules.wlhy.wlxypt.entity.WlxyptShippingNode;
import org.jeecg.modules.wlhy.yunfutong.util.TestHttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

;

/**
 * 物流信用平台对接接口
 */
@Service
@Slf4j
public class WlxyptServiceApi {

    @Autowired
    private RedisUtil redisUtil;

    @Value(value = "${ysb-daikai.baseUrl:}")
    private String localbaseUrl;


    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;


    @Autowired
    private WaybillRouteService waybillRouteService;

    @Autowired
    private GeneratePDF generatePDF;


    //文件保存地址路径
    public static String SAVE_CONTRACT_ADDR = "documents" + File.separator + DateUtils.getDate("yyyyMMdd") + File.separator;

    //PDF后缀
    public static String PDF_SUFFIX = ".text";


    /**
     * 登录获取token
     */
    public  Result<?> login(){
        if(!HyCfgUtil.isUsed("xly_ect")){
            throw new JeecgBootException("etc服务暂未开启,请联系管理员。");
        }
        String baseUrl = HyCfgUtil.getCfgItem2("xly_ect","url");
        String account = HyCfgUtil.getCfgItem2("xly_ect","account");
        String pwd = HyCfgUtil.getCfgItem2("xly_ect","pwd");
        JSONObject json = new JSONObject();
        json.put("account", account);
        json.put("pwd", MD5Util.encode(pwd));
        String url = baseUrl+"api/ws/ent/login/login";
        log.info(json.toString());
        HttpEntity entity;
        // 实体类转换为Map
        Map<String, String> map2 = JSON.parseObject(JSON.toJSONString(json), Map.class);
        entity = new StringEntity(JSONUtil.toJsonStr(map2), "utf-8");
        log.info("开始发送登录请求,请求参数为" + map2);
        String result = TestHttpClientUtil.httpPost(url, entity);
        log.info("发送登录请求完成，返回参数为" + result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.getString("code").equals("200")) {
            Result<?> reqResult = new Result<>();
            return reqResult.error500(jsonObject.get("message").toString());

        }
        JSONObject data = jsonObject.getJSONObject("data");
        String token = data.getString("token");
        log.info("获取到token,token为" + token);
        redisUtil.set("WSAPIToken",token,60*60*24);
        return Result.OK(token);

    }

    /**
     * 司机车辆注册
     */
    public Result<?> addDriver(HyShippingNote hyShippingNote,HyDriver driver, HyVehicle vehicle,String token) throws IOException {
        if (driver!=null){
            if(!HyCfgUtil.isUsed("xly_ect")){
                throw new JeecgBootException("etc服务暂未开启,请联系管理员。");
            }
            String baseUrl = HyCfgUtil.getCfgItem2("xly_ect","url");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            WlxyptDriver wlxyptDriver  = new WlxyptDriver();
            wlxyptDriver.setMobile(driver.getTelephone());
            wlxyptDriver.setRealName(driver.getDriverName());
            wlxyptDriver.setIdNo(driver.getIdcard());
            if (driver.getIdcardValidFrom()!=null){
                wlxyptDriver.setIdSignDate(sdf.format(driver.getIdcardValidFrom()));
                if (driver.getIdcardExpiredDate().toString().contains("9999")){
                    wlxyptDriver.setIdExpiryDate("9999-12-30");
                }else {
                    wlxyptDriver.setIdExpiryDate(sdf.format(driver.getIdcardExpiredDate()));
                }
            }
            wlxyptDriver.setImageType("jpg");
            String idcardImg= localbaseUrl + "/sys/common/static/" + encode(driver.getIdcardImg(),"utf-8");
            String idcardImgBack = localbaseUrl + "/sys/common/static/" + encode(driver.getIdcardImgBack(),"utf-8");
            String driverImg = localbaseUrl + "/sys/common/static/" + encode(driver.getDriverImg(),"utf-8");
            Result driverSignAndRegister = generatePDF.xinluyundaikai(hyShippingNote.getOrderId(), driver, null);
            String driverInvoiceAgreement = null;
            if(driverSignAndRegister.isSuccess()){
                driverInvoiceAgreement = localbaseUrl + "/sys/common/static/"+encode(driverSignAndRegister.getResult().toString(),"utf-8");
            }else{
                return Result.error("税务代开合同生成失败:"+driverSignAndRegister.getMessage());
            }
            log.info("driverInvoiceAgreement===="+driverInvoiceAgreement);

            try {
                wlxyptDriver.setIdCardFrontInfo(PdfUtil.encodeImageToBase64(idcardImg));
                wlxyptDriver.setIdCardBackInfo(PdfUtil.encodeImageToBase64(idcardImgBack));
                wlxyptDriver.setDriverCardMasterInfo(PdfUtil.encodeImageToBase64(driverImg));
                wlxyptDriver.setContractInfo(PdfUtil.encodeImageToBase64(driverInvoiceAgreement));
            } catch (Exception e) {
                e.printStackTrace();
            }
            wlxyptDriver.setDriverType(driver.getVehicleClass());
            if (driver.getValidPeriodTo().toString().contains("9999")){
                wlxyptDriver.setDriverExpiryDate("9999-12-30");
            }else {
                wlxyptDriver.setDriverExpiryDate(sdf.format(driver.getValidPeriodTo()));
            }

            String reqUrl = baseUrl+"api/foreign/driver/register";
            // 实体类转换为Map
            Map<String, String> map2 = JSON.parseObject(JSON.toJSONString(wlxyptDriver), Map.class);
            log.info("开始发送添加司机请求,请求参数为" + map2);
            HttpEntity entity = new StringEntity(JSONUtil.toJsonStr(map2), "utf-8");
            String result = TestHttpClientUtil.post(reqUrl, entity,token);
            log.info("返回参数为"+result.toString());
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (!jsonObject.getString("code").equals("200")) {
                return Result.error(jsonObject.get("message").toString());
            }
            return Result.OK();
        }else {
            return Result.error("司机信息不存在");
        }
    }
    /**
     * 查询司机
     */
    public Result<?> query(String idcard,String token){
        if(!HyCfgUtil.isUsed("xly_ect")){
            throw new JeecgBootException("etc服务暂未开启,请联系管理员。");
        }
        String baseUrl = HyCfgUtil.getCfgItem2("xly_ect","url");
        String reqUrl = baseUrl+"api/foreign/driver/query/"+idcard;
        String result = TestHttpClientUtil.Get(reqUrl,token);
        log.info("返回参数为"+result.toString());
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.getString("code").equals("200")) {
            return Result.error(jsonObject.get("message").toString());
        }
        return Result.OK();

    }
    /**
     * 查询司机
     */
    public Result<?> queryShippingNote(String shippingNoteNum,String token){
        if(!HyCfgUtil.isUsed("xly_ect")){
            throw new JeecgBootException("etc服务暂未开启,请联系管理员。");
        }
        String baseUrl = HyCfgUtil.getCfgItem2("xly_ect","url");
        String reqUrl = baseUrl+"/api/foreign/order/query/"+shippingNoteNum;
        String result = TestHttpClientUtil.Get(reqUrl,token);
        log.info("返回参数为"+result.toString());
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.getString("code").equals("200")) {
            return Result.error(jsonObject.get("message").toString());
        }
        return Result.OK();

    }


    /**
     * 上传运单
     * @param
     */
    public Result<?> addShippingNode(HyShippingNote hyShippingNote, List<HyShippingNoteBill> hyShippingNoteBills,HyDriver driver,HyVehicle vehicle,String token) throws Exception {

        if(!HyCfgUtil.isUsed("xly_ect")){
            throw new JeecgBootException("etc服务暂未开启,请联系管理员。");
        }
        String baseUrl = HyCfgUtil.getCfgItem2("xly_ect","url");
        WlxyptShippingNode wlxyptShippingNode = new WlxyptShippingNode();
        wlxyptShippingNode.setId(hyShippingNote.getShippingNoteNumber());
        wlxyptShippingNode.setDeliveryTime(hyShippingNote.getStatusDtLoading());
        wlxyptShippingNode.setUnloadTime(hyShippingNote.getStatusDtUnloading());
        wlxyptShippingNode.setStartPlace(hyShippingNote.getSendAddress());
        wlxyptShippingNode.setEndPlace(hyShippingNote.getReceiveAddress());
        wlxyptShippingNode.setFreight(hyShippingNote.getDescriptionOfGoods());
        if (hyShippingNote.getGoodsUnit().equals("2")||hyShippingNote.getGoodsUnit().equals("3")){
            return Result.error("该代开不支持此货物类型运输方式");
        }
        wlxyptShippingNode.setFreightWeight(hyShippingNote.getGoodsWeightUnloading());
        //计算运费（存在多条）
        BigDecimal totalAmt = hyShippingNoteBills.stream().map(HyShippingNoteBill::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
        wlxyptShippingNode.setMoney(totalAmt);
        wlxyptShippingNode.setConsignor(hyShippingNote.getSendContactName());
        wlxyptShippingNode.setConsignorMobile(hyShippingNote.getSendContactTel());
        wlxyptShippingNode.setConsignee(hyShippingNote.getReceiveContactName());
        wlxyptShippingNode.setConsigneeMobile(hyShippingNote.getReceiveContactTel());
        wlxyptShippingNode.setDriverIdNumber(driver.getIdcard());
        wlxyptShippingNode.setCarNumber(vehicle.getVehicleNumber());
        //金猫这为1，如为其他则改为4
        wlxyptShippingNode.setInvoiceType(4);
        //上传轨迹
        try {
            log.info("开始组装轨迹文件");
            String routerPath = getRouterPath(vehicle,hyShippingNote);
            wlxyptShippingNode.setTrackUploadType("text");
            wlxyptShippingNode.setTrackInfo(encode(routerPath,"utf-8"));

        } catch (Exception e) {
            log.error(e.getMessage());
        }
        //上传资金流水
        log.info("开始组装资金流水");

        List<String> moneyInfos = new ArrayList<>();
        String moneyInfo = null;
        String bankUrl = null;
        for (HyShippingNoteBill hyShippingNoteBill : hyShippingNoteBills) {
            if (!hyShippingNoteBill.getShippingNoteNumber().contains("YD")){
                log.info("旧数据推送");
                bankUrl = localbaseUrl + "/sys/common/static/" + encode(hyShippingNoteBill.getBankHdImg(),"utf-8");
                moneyInfo  = PdfUtil.encodeImageToBase64(bankUrl);
                moneyInfos.add(moneyInfo);
                String type = hyShippingNoteBill.getBankHdImg();
                log.info("回单类型=="+type);
                wlxyptShippingNode.setMoneyUploadType(ImageUtil.getImageType(type));
            }else {

                /*if (hyShippingNoteBill.getBankHd()!=null){
                    bankUrl= localbaseUrl + "/sys/common/static/" + encode(hyShippingNoteBill.getBankHd(),"utf-8");
                    moneyInfo  = PdfUtil.encodeImageToBase64(bankUrl);
                    moneyInfos.add(moneyInfo);
                    wlxyptShippingNode.setMoneyUploadType("pdf");
                }else if (hyShippingNoteBill.getBankHdImg()!=null){
                    bankUrl = localbaseUrl + "/sys/common/static/" + encode(hyShippingNoteBill.getBankHdImg(),"utf-8");
                    moneyInfo  = PdfUtil.encodeImageToBase64(bankUrl);
                    moneyInfos.add(moneyInfo);
                    String type = hyShippingNoteBill.getBankHdImg();
                    log.info("回单类型=="+type);
                    wlxyptShippingNode.setMoneyUploadType(ImageUtil.getImageType(type));
                }else {
                    continue;
                }*/
                if (StringUtils.isEmpty(hyShippingNoteBill.getBankHdImg())&&StringUtils.isEmpty(hyShippingNoteBill.getBankHd())){
                    return Result.error("请上传电子回单图片");
                }else {
                    if (StringUtils.isNotEmpty(hyShippingNoteBill.getBankHdImg())) {
                        log.info("电子回单图片");
                        bankUrl = localbaseUrl + "/sys/common/static/" + encode(hyShippingNoteBill.getBankHdImg(),"utf-8");
                        moneyInfo  = PdfUtil.encodeImageToBase64(bankUrl);
                        moneyInfos.add(moneyInfo);
                        String type = hyShippingNoteBill.getBankHdImg();
                        log.info("回单类型=="+type);
                        wlxyptShippingNode.setMoneyUploadType(ImageUtil.getImageType(type));
                    } else {
                        log.info("电子回单");
                        bankUrl= localbaseUrl + "/sys/common/static/" + encode(hyShippingNoteBill.getBankHd(),"utf-8");
                        moneyInfo  = PdfUtil.encodeImageToBase64(bankUrl);
                        moneyInfos.add(moneyInfo);
                        wlxyptShippingNode.setMoneyUploadType("pdf");
                    }
                }
            }

        }
        log.info("bankUrl==="+bankUrl);
        wlxyptShippingNode.setMoneyInfos(moneyInfos);
        //上传合同
        log.info("开始组装运输合同");
        if (StringUtils.isNotEmpty(hyShippingNote.getShippingContract())){
            wlxyptShippingNode.setContractUploadType("pdf");
            String contractUrl = localbaseUrl + "/sys/common/static/" + encode(hyShippingNote.getShippingContract(),"utf-8");
            log.info("contractUrl==="+contractUrl);
            wlxyptShippingNode.setContractInfo(PdfUtil.encodeImageToBase64(contractUrl));
        }else {
            return Result.error("运输合同不能为空");
        }


        String reqUrl = baseUrl+"/api/foreign/order/add";
        // 实体类转换为Map
        Map<String, String> map2 = JSON.parseObject(JSON.toJSONString(wlxyptShippingNode), Map.class);
        log.info("开始发送添加运单请求");
        HttpEntity entity = new StringEntity(JSONUtil.toJsonStr(map2), "utf-8");
        String result = TestHttpClientUtil.post(reqUrl, entity,token);
        log.info(result.toString());
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.getString("code").equals("200")) {
            return Result.error(jsonObject.get("message").toString());
        }
        return Result.OK();

    }

    /**
     * 删除运单
     * @param
     * @param
     * @return
     * @throws Exception
     */
    public Result<?> deleteShippingNode(String shippingNoteNumber,String token) throws IOException {
        if(!HyCfgUtil.isUsed("xly_ect")){
            throw new JeecgBootException("etc服务暂未开启,请联系管理员。");
        }
        String baseUrl = HyCfgUtil.getCfgItem2("xly_ect","url");
        String reqUrl = baseUrl+"api/foreign/order/remove/"+shippingNoteNumber;
        String result = TestHttpClientUtil.doDelete(reqUrl,token);
        log.info("返回参数为"+result.toString());
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.getString("code").equals("200")) {
            return Result.error(jsonObject.get("message").toString());
        }
        return Result.OK();
    }


    private String getRouterPath(HyVehicle vehicle, HyShippingNote hyShippingNote) throws Exception {

        //agl，正北方向夹角，（0--359 ，0正北）
        //gtm 接受时间
        String base64File = null;
        if (vehicle!=null){
            String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtLoading());
            String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
            Date startTimeDate = DateUtils.stringToDateTime(startTime);
            Date endTimeDate = DateUtils.stringToDateTime(endTime);
            WaybillRouteVO waybillRouteVO = new WaybillRouteVO();
            if (!endTimeDate.after(startTimeDate)) {
                throw new JeecgBootException("结束时间不能在开始时间之前！");
            }
            //如果开启了历史轨迹并且保存过轨迹，就调用已经保存的轨迹
            if (StrUtil.isNotEmpty(hyShippingNote.getShippingNoteNumber()) && HyCfgUtil.isUsed2("history_trace")) {
                //中交轨迹只能查询6个月的，超出6个月的可以尝试读取本地轨迹记录
                Integer second = DateUtils.getDifferentDaysByMillisecond(startTimeDate, new Date());
                if (second > (3600 * 24 * 180)) {
                   log.info("进入本地历史记录");
                    waybillRouteVO  = waybillRouteService.getWaybillByFile(hyShippingNote.getShippingNoteNumber());
                }else {
                    log.info("去请求中交");
                    waybillRouteVO = waybillRouteService.getRouterPath(vehicle.getVehicleNumber(), startTime, endTime, "");
                }
            }else {
                waybillRouteVO = waybillRouteService.getRouterPath(vehicle.getVehicleNumber(), startTime, endTime, "");
            }
            if (waybillRouteVO==null){
                throw new JeecgBootException(hyShippingNote.getShippingNoteNumber()+"轨迹不存在");
            }
            List<PointDataListVO> pointDataList = waybillRouteVO.getPointDataList();
            List<Map<String,Object>> guijiList = new ArrayList<Map<String, Object>>();
            for (PointDataListVO pointDataListVO : pointDataList) {
                //时间,经度,维度,速度
                JSONObject json = new JSONObject();;
                json.put("gtm",pointDataListVO.getReceiveTime());
                json.put("lat",pointDataListVO.getLat());
                json.put("lon",pointDataListVO.getLng());
                json.put("spd",pointDataListVO.getCs());
                guijiList.add(json);
            }
            // 将字符串存入临时文件
            String tempPath = writeToTempFile(guijiList.toString());
            log.info("轨迹文件临时地址为"+tempPath);

            //base64File = Base64Util.encodeBase64File(tempPath);
            String fileUrl = localbaseUrl + "/sys/common/static/" + encode(tempPath,"utf-8");
            log.info("fileUrl"+fileUrl);
            base64File = PdfUtil.encodeImageToString(fileUrl);


        }
        return base64File;
    }

    private String writeToTempFile(String guiji) {

        String outputName2 = "";
        try {
            log.info("写入临时文件");
            //输出路径
            String pathSubfix = uploadpath + File.separator;
            String outputName1 =pathSubfix+SAVE_CONTRACT_ADDR;
            log.info("输出路径1是"+pathSubfix);
            outputName2 = SAVE_CONTRACT_ADDR  + DateUtils.getDate("yyyyMMddHHmmss") + PDF_SUFFIX;
            String outputName = pathSubfix + outputName2;
            log.info("outputName=="+outputName);
            log.info("outputName2=="+outputName2);
            log.info("outputName1"+outputName1);
            if (!FileUtil.exist(outputName1)) {
                log.info("创建输出文件夹");
                FileUtil.mkdir(outputName1);
            }
            // 将字符串写入文件
            FileWriter fileWriter = new FileWriter(outputName);
            fileWriter.write(guiji);
            fileWriter.close();
            log.info(outputName2);
        } catch (IOException e) {
            e.printStackTrace();

        }
        return outputName2;


    }



    /**
     * 图片转义
     */
    private String encode(String url, String chartSet) {

        {
            try {
                Matcher matcher = Pattern.compile("[^\\x00-\\xff]").matcher(url);//双字节,包括中文和中文符号[^\x00-\xff]  中文[\u4e00-\u9fa5]
                while (matcher.find()) {
                    String tmp = matcher.group();
                    url = url.replaceAll(tmp, java.net.URLEncoder.encode(tmp, chartSet));
                }
            } catch (UnsupportedEncodingException e) {
                log.error("双字节编码异常：", e);
            }
            return url;
        }
    }





}

